﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;
using System.Data.SQLite;
using System.Data.Common;

namespace ImageSorting
{
    public partial class Form1 : Form
    {
        static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();
        int counter = 0;
        String SqlDB;
        public Form1()
        {
            InitializeComponent();
        }

        // Применяем процедуру выбора папки к конкретному TextBox'у
         private void browseBtn_Click(object sender, EventArgs e)
         {
             ChooseFolder(textBox1);
         }
      
         private void browseBtn2_Click(object sender, EventArgs e)
         {
             ChooseFolder(textBox2);
         }

        // Берём путь к папке из компонента FolderBrowseDialog и сохраняем его в св-во Text TextBox'a
         public void ChooseFolder(TextBox temptxt)
         {
             if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
             {
                 temptxt.Text = folderBrowserDialog1.SelectedPath;
             }
         }

         private void startBtn_Click(object sender, EventArgs e)
         {
             Console.WriteLine("Начали");
             DirectoryInfo di = new DirectoryInfo(textBox1.Text);
             try
             {
                 // Determine whether the directory exists.
                 if (di.Exists)
                 {
                     // Indicate that the directory already exists.
                     Console.WriteLine("Папка существует всё тип топ");
                 }
                 else
                 {
                     MessageBox.Show("Такой папки не существует");
                     return;
                 }

             }
             catch (Exception ex)
             {
                 Console.WriteLine("The process failed: {0}", ex.ToString());
             }
             finally { }
             MessageBox.Show("Приступаем к выполнению");
             counter = 0;
             label3.Text = "0";
             SqlDB = "";
             SqlDB += textBox2.Text + @"\pictures.db3";
             CheckDB(SqlDB);
             CreateTable(SqlDB);
             WalkDirectoryTree(di);
             CloseDB(SqlDB);
             MessageBox.Show("Задание выполнено, было отсортировано " + counter + " файлов" );
             //if (checkBox1.Checked)
             //{
             //    String Filter = textBox3.Text;
             //}
         }
         
        private void WalkDirectoryTree(DirectoryInfo root)
         {
             FileInfo[] files = null;
             DirectoryInfo[] subDirs = null;
             Console.WriteLine("Начали");
             // First, process all the files directly under this folder
             try
             {
                 files = root.GetFiles("*.*");
             }
             // This is thrown if even one of the files requires permissions greater
             // than the application provides.
             catch (UnauthorizedAccessException e)
             {
                 // This code just writes out the message and continues to recurse.
                 // You may decide to do something different here. For example, you
                 // can try to elevate your privileges and access the file again.
                 log.Add(e.Message);
             }

             catch (System.IO.DirectoryNotFoundException e)
             {
                 Console.WriteLine(e.Message);
             }

             if (files != null)
             {
                 foreach (FileInfo fi in files)
                 {
                     // In this example, we only access the existing FileInfo object. If we
                     // want to open, delete or modify the file, then
                     // a try-catch block is required here to handle the case
                     // where the file has been deleted since the call to TraverseTree().
                     Console.WriteLine(fi.FullName);
                     //textBox4.Text += Environment.NewLine+fi.FullName;
                    // textBox4.Text += Environment.NewLine + GetMD5HashFromFile(fi.FullName);
                     if (CheckTable(SqlDB,fi) == false)
                     {
                         textBox4.Text += Environment.NewLine + "Такого файла нет= " + fi.Name;
                         GetImageResolution(fi);
                     }
                     else
                     {
                         textBox4.Text += Environment.NewLine + "Такой файл уже есть= " + fi.Name;
                     }
                 }

                 // Now find all the subdirectories under this directory.
                 subDirs = root.GetDirectories();

                 foreach (DirectoryInfo dirInfo in subDirs)
                 {
                     // Resursive call for each subdirectory.
                     WalkDirectoryTree(dirInfo);
                 }
             }
         }

         private void GetImageResolution(FileInfo imagesource)
         {
             try
             {
                 if (checkBox1.Checked)
                 {
                     if (CheckFileToImage(imagesource))
                     {
                         if (imagesource.FullName.Contains(textBox3.Text))
                         {
                             InsertInTable(SqlDB, imagesource);
                             MoveTo(imagesource);
                             counter += 1;
                             label3.Text = counter.ToString();
                             this.Refresh();
                         }
                         else
                         {
                             InsertInTable(SqlDB, imagesource);
                             Image i = Image.FromFile(imagesource.FullName);
                             SizeF sz = i.PhysicalDimension;
                             i.Dispose();
                             // CheckResolution(ref sz);
                             textBox4.Text += Environment.NewLine + "Высота= " + sz.Height + "Ширина= " + sz.Width;
                             MoveTo(imagesource, sz.Height, sz.Width);
                             counter += 1;
                             label3.Text = counter.ToString();
                             this.Refresh();
                         }
                     }
                 }
                 else
                 {
                     if (CheckFileToImage(imagesource))
                     {
                             InsertInTable(SqlDB, imagesource);
                             Image i = Image.FromFile(imagesource.FullName);
                             SizeF sz = i.PhysicalDimension;
                             i.Dispose();
                             // CheckResolution(ref sz);
                             textBox4.Text += Environment.NewLine + "Высота= " + sz.Height + "Ширина= " + sz.Width;
                             MoveTo(imagesource, sz.Height, sz.Width);
                             counter += 1;
                             label3.Text = counter.ToString();
                             this.Refresh();
                     }
                 }
                 

             }
             catch
             {
             }
            
         }

         private SizeF CheckResolution(ref SizeF sz)
         {
             return sz;
         }
         private bool CheckFileToImage(FileInfo imagesource)
         {
            
             if (imagesource.Extension.ToLower() == ".jpg")
             {
                 textBox4.Text += Environment.NewLine + imagesource.Extension;
                 return true;
             }
             else if (imagesource.Extension == ".bmp")
             {
                 textBox4.Text += Environment.NewLine + imagesource.Extension;
                 return true;
             }
             else if (imagesource.Extension == ".png")
             {
                 textBox4.Text += Environment.NewLine + imagesource.Extension;
                 return true;
             }
             else
             {
                 return false;
             }
      
         }

         private void MoveTo(FileInfo file)
         {
             String str = textBox2.Text + @"\" + textBox3.Text;
             String newfile = str + @"\" + file.Name;
             String oldfile = file.FullName;
             try
             {

                 if (Directory.Exists(str))
                 {

                     if (File.Exists(newfile))
                     {
                         if (checkBox2.Checked)
                         {
                             File.Delete(newfile);
                             File.Copy(file.FullName, newfile);
                         }
                         else
                         {
                             File.Delete(newfile);
                             File.Move(oldfile, newfile);
                         }
                     }
                     else
                     {
                         if (checkBox2.Checked)
                         {
                             File.Delete(newfile);
                             File.Copy(file.FullName, newfile);
                         }
                         else
                         {
                             File.Delete(newfile);
                             File.Move(oldfile, newfile);
                         }
                     }
                 }
                 else
                 {
                     Directory.CreateDirectory(str);
                     if (checkBox2.Checked)
                     {
                         File.Delete(newfile);
                         File.Copy(file.FullName, newfile);
                     }
                     else
                     {
                         File.Delete(newfile);
                         File.Move(oldfile, newfile);
                     }
                 }
             }
             catch (Exception e)
             {
                 Console.WriteLine("The process failed: {0}", e.ToString());
             }
         }
         private void MoveTo(FileInfo file, float h, float w)
         { 
             String str = textBox2.Text + @"\" + h + @"x" + w;
             String newfile = str + @"\" + file.Name;
             String oldfile = file.FullName;
            try 
             {

             if (Directory.Exists(str))
             {
               
                 if (File.Exists(newfile))
                 {
                     if (checkBox2.Checked)
                     {
                         File.Delete(newfile);
                         File.Copy(file.FullName, newfile);
                     }
                     else
                     {
                         File.Delete(newfile);
                         File.Move(oldfile, newfile);
                     }
                 }
                 else
                 {
                     if (checkBox2.Checked)
                     {
                         File.Delete(newfile);
                         File.Copy(file.FullName, newfile);
                     }
                     else
                     {
                         File.Delete(newfile);
                         File.Move(oldfile, newfile);
                     }
                 }
             }
             else
             {
                 Directory.CreateDirectory(str);
                 if (checkBox2.Checked)
                 {
                     File.Delete(newfile);
                     File.Copy(file.FullName, newfile);
                 }
                 else
                 {
                     File.Delete(newfile);
                     File.Move(oldfile, newfile);
                 }
             }
             }
            catch (Exception e)
            {
                Console.WriteLine("The process failed: {0}", e.ToString());
            }

         }
         protected string GetMD5HashFromFile(string fileName)
         {
             FileStream file = new FileStream(fileName, FileMode.Open);
             MD5 md5 = new MD5CryptoServiceProvider();
             byte[] retVal = md5.ComputeHash(file);
             file.Close();

             StringBuilder sb = new StringBuilder();
             for (int i = 0; i < retVal.Length; i++)
             {
                 sb.Append(retVal[i].ToString("x2"));
             }
             return sb.ToString();
         }

         private void checkBox2_CheckedChanged(object sender, EventArgs e)
         {
             if (checkBox2.Checked)
             {
                 checkBox2.Text = "Копировать файлы";
             }
             else
             {
                 checkBox2.Text = "Перемещать файлы";
             }
         }

         private void checkBox1_CheckedChanged(object sender, EventArgs e)
         {
             if (checkBox1.Checked)
             {
                 checkBox1.Text = "Отбор по имен включён";
             }
             else
             {
                 checkBox1.Text = "Отбор по имени выключен";
             }
         }
         private void CheckDB(String DBname)
         {
             if (File.Exists(DBname) == false)
             {
                 try
                 {
                     SQLiteConnection.CreateFile(DBname);
                 }
                 finally
                 {
                     MessageBox.Show("Поздравляем вас, база успешно создана");
                 }
             }

            
         }
         private void OpenDB(String DBname)
         {
             // Create a connection and a command
             using (DbConnection cnn = new SQLiteConnection("Data Source=" + DBname))
             cnn.Open();
         }
         private void CloseDB(String DBname)
         {
             // Create a connection and a command
             using (DbConnection cnn = new SQLiteConnection("Data Source=" + DBname))
                 cnn.Close();
         }
         private void InsertInTable(String DBname,FileInfo FI)
         {
             // Create a connection and a command
             using (DbConnection cnn = new SQLiteConnection("Data Source="+ DBname))
             using (DbCommand cmd = cnn.CreateCommand())
             {
                 cnn.Open();
                 // Create a parameterized insert command
                 cmd.CommandText = "INSERT INTO PICTURES (MYVALUE) VALUES(?)";
                 cmd.Parameters.Add(cmd.CreateParameter());
                 cmd.Parameters[0].Value = GetMD5HashFromFile(FI.FullName);
                 cmd.ExecuteNonQuery();
             }
         }
         private void CreateTable(String DBname)
         {
             // Create a connection and a command
             using (DbConnection cnn = new SQLiteConnection("Data Source=" + DBname))
             using (DbCommand cmd = cnn.CreateCommand())
             {
                 cnn.Open();
                 // Create a table in the database
                 try
                 {
                     cmd.CommandText = "CREATE TABLE PICTURES (ID INTEGER PRIMARY KEY, MYVALUE VARCHAR(50))";
                     cmd.ExecuteNonQuery();
                 }
                 catch (Exception ex)
                 {
                     Console.WriteLine(ex.ToString());
                 }
             }
         }
         private bool CheckTable(String DBname, FileInfo FI)
         {
             // Create a connection and a command
             using (DbConnection cnn = new SQLiteConnection("Data Source=" + DBname))
             using (DbCommand cmd = cnn.CreateCommand())
             {
                 cnn.Open();
                 // Create a table in the database
                 cmd.CommandText = "SELECT * FROM PICTURES";
                 using (DbDataReader reader = cmd.ExecuteReader())
                 {
                     while (reader.Read())
                     {
                         if (reader[1].ToString() == GetMD5HashFromFile(FI.FullName).ToString())
                         {
                             textBox4.Text += Environment.NewLine + (String.Format("ID = {0}, MYVALUE = {1}", reader[0], reader[1]));
                             return true;
                         }
                     }
                 }
                 return false;
             }
         }
    }
}
